<template>
  <div class="app-container">
    <!-- 添加或修改企业资讯页面 -->
    <el-card>
      <div slot="header">
        <span>{{ title }}</span>
      </div>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="缩略图" prop="thumbnailUrl">
          <EditImage
            v-model="form.thumbnailUrl"
            :cropper-config="{
              autoCrop: true,
              autoCropWidth: 200,
              autoCropHeight: 300,
              fixedBox: false,
              outputType: 'png'
            }"
            :dialog-width="'800px'"
            :cropper-height="400"
            upload-tip="支持 JPG、PNG 格式，建议尺寸 200x300，文件大小不超过 5MB"
            placeholder-text="请上传资讯缩略图，建议尺寸 200x300 像素"
            cropper-title="资讯图片裁剪"
            :max-file-size="5"
            @image-cropped="onImageCropped"
            @image-removed="onImageRemoved"
          />
        </el-form-item>
        <el-form-item label="标题" prop="title">
          <el-input v-model="form.title" placeholder="请输入标题" />
        </el-form-item>
        <el-form-item label="描述" prop="desc">
          <el-input v-model="form.desc" placeholder="请输入描述" />
        </el-form-item>
        <el-form-item label="内容">
          <Editor 
            v-model="form.content" 
            :min-height="192"
            :upload-url="BASE_API + '/common/upload'"
            :upload-type="3"
            :file-size="5"
            :use-custom-image-handler="true"
            @on-editor-change="onEditorChange"
            @on-text-change="onEditorTextChange"
            @on-selection-change="onEditorSelectionChange"
            @image-added="handleImageAdded"
          />
        </el-form-item>
        <el-form-item label="链接地址" prop="linkUrl">
          <el-input v-model="form.linkUrl" placeholder="请输入链接地址" />
        </el-form-item>
        <el-form-item label="分类" prop="typeId">
          <el-select v-model="form.typeId" placeholder="请选择分类" clearable>
            <el-option
              v-for="item in typeOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
          <div v-if="form.typeId" style="margin-top: 5px; color: #909399; font-size: 12px;">
            当前选择：{{ getTypeName(form.typeId) }}
          </div>
        </el-form-item>
        <el-form-item label="Banner页面" prop="bannerPage">
          <el-select v-model="form.bannerPage" placeholder="请选择Banner页面" clearable>
            <el-option
              v-for="(item, index) in bannerPageOptions"
              :key="index"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div class="form-actions">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-card>


  </div>
</template>

<script>
import { getNews, addNews, updateNews, uploadNewsFile } from "@/api/system/news"
import EditImage from '@/components/EditImage/EditImage.vue'
import Editor from '@/components/Editor/index.vue'
import { listNews_type } from "@/api/system/news_type"
import { listBannerPage } from "@/api/system/banner"
import { BASE_FILE_URL, BASE_API } from '@/utils/constants'

export default {
  name: "AddNews",
  components: { EditImage, Editor },
  data() {
    return {
      title: "",
      form: {},
      BASE_API: BASE_API, // 添加BASE_API到data中
      rules: {
        thumbnailUrl: [
          { required: true, message: "缩略图不能为空", trigger: "blur" }
        ],
        title: [
          { required: true, message: "标题不能为空", trigger: "blur" }
        ],
        desc: [
          { required: true, message: "描述不能为空", trigger: "blur" }
        ],
        typeId: [
          { required: true, message: "请选择分类", trigger: "change" }
        ],
      },
      typeOptions: [],
      bannerPageOptions: [],
      // 图片裁剪相关
      croppedImageBlob: null
    }
  },
  created() {
    this.getTypeOptions()
    this.getBannerPageOptions()
    this.initForm()
    // 设置页面标题
    this.setPageTitle()
  },
  watch: {
    '$route.query': {
      handler(newQuery) {
        // 当查询参数变化时重新初始化表单
        this.initForm()
      },
      immediate: false
    }
  },
  methods: {
    getTypeOptions() {
      listNews_type().then(res => {
        if (res && (res.data || res.rows)) {
          this.typeOptions = res.data || res.rows
        } else if (Array.isArray(res)) {
          this.typeOptions = res
        } else {
          this.typeOptions = []
        }
      })
    },
    getBannerPageOptions() {
      listBannerPage().then(res => {
        if (res && (res.data || res.rows)) {
          this.bannerPageOptions = res.data || res.rows
        } else if (Array.isArray(res)) {
          this.bannerPageOptions = res
        } else {
          this.bannerPageOptions = []
        }
      }).catch(error => {
        console.error('获取Banner页面选项失败:', error)
        this.bannerPageOptions = []
      })
    },
    /** 根据typeId获取分类名称 */
    getTypeName(typeId) {
      const found = this.typeOptions.find(item => item.id == typeId)
      return found ? found.name : typeId
    },
    initForm() {
      const { id } = this.$route.query
      if (id) {
        this.title = "修改企业资讯"
        this.loadEditData(id)
      } else {
        this.title = "添加企业资讯"
        this.reset()
      }
      // 更新页面标题
      this.setPageTitle()
    },
    setPageTitle() {
      // 设置浏览器标签页标题
      document.title = this.title + ' - 企业资讯管理'
    },
    loadEditData(id) {
      getNews(id).then(response => {
        this.form = response.data
      }).catch(error => {
        this.$modal.msgError("获取数据失败：" + (error.message || "未知错误"))
        this.$router.go(-1)
      })
    },
    // 清理和转义HTML内容，确保是合规的HTML字符串
    sanitizeHtmlContent(htmlContent) {
      if (!htmlContent || typeof htmlContent !== 'string') {
        return '';
      }
      
      // 如果内容为空，返回空字符串
      if (htmlContent.trim() === '') {
        return '';
      }
      
      // 使用更简单的方法：只转义必要的字符，保持HTML结构
      let cleanedHtml = this.simpleHtmlClean(htmlContent);
      
      // 如果内容为空，返回空字符串
      if (!cleanedHtml || cleanedHtml.trim() === '') {
        return '';
      }
      
      // 确保HTML结构完整
      if (!cleanedHtml.startsWith('<')) {
        cleanedHtml = '<p>' + cleanedHtml + '</p>';
      }
      
      // 最终清理：移除多余的空白字符和换行符
      cleanedHtml = cleanedHtml
        .replace(/\s+/g, ' ')  // 多个空白字符替换为单个空格
        .replace(/>\s+</g, '><')  // 标签之间的空白字符
        .trim();
      
      return cleanedHtml;
    },
    
    // 简单的HTML清理方法，避免过度转义
    simpleHtmlClean(html) {
      if (!html) return '';
      
      // 最保守的清理：只转义最基本的危险字符
      // 保持HTML结构完全不变
      return html
        .replace(/&(?!amp;|lt;|gt;|quot;|#39;|#x[0-9a-fA-F]+;)/g, '&amp;');  // 只转义未转义的&
    },
    
    // 递归清理HTML元素
    cleanHtmlElement(element) {
      if (element.nodeType === Node.TEXT_NODE) {
        // 文本节点，只转义必要的字符
        return this.escapeHtmlText(element.textContent);
      }
      
      if (element.nodeType === Node.ELEMENT_NODE) {
        const tagName = element.tagName.toLowerCase();
        
        // 允许的HTML标签
        const allowedTags = [
          'p', 'div', 'span', 'br', 'hr',
          'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
          'strong', 'b', 'em', 'i', 'u', 's', 'del',
          'ul', 'ol', 'li',
          'blockquote', 'code', 'pre',
          'a', 'img', 'table', 'thead', 'tbody', 'tr', 'th', 'td',
          'sup', 'sub', 'mark', 'small'
        ];
        
        // 如果是不允许的标签，只保留其内容
        if (!allowedTags.includes(tagName)) {
          let content = '';
          for (let child of element.childNodes) {
            content += this.cleanHtmlElement(child);
          }
          return content;
        }
        
        // 清理属性
        const allowedAttributes = {
          'a': ['href', 'title', 'target'],
          'img': ['src', 'alt', 'title', 'width', 'height'],
          'table': ['width', 'border', 'cellspacing', 'cellpadding'],
          'td': ['width', 'height', 'colspan', 'rowspan'],
          'th': ['width', 'height', 'colspan', 'rowspan']
        };
        
        let attributes = '';
        if (allowedAttributes[tagName]) {
          for (let attr of element.attributes) {
            if (allowedAttributes[tagName].includes(attr.name)) {
              // 对于图片src属性，保持URL不变，只转义特殊字符
              if (attr.name === 'src' && tagName === 'img') {
                const escapedValue = this.escapeHtmlAttribute(attr.value);
                attributes += ` ${attr.name}="${escapedValue}"`;
              } else {
                // 其他属性正常转义
                const escapedValue = this.escapeHtmlAttribute(attr.value);
                attributes += ` ${attr.name}="${escapedValue}"`;
              }
            }
          }
        }
        
        // 处理子元素
        let content = '';
        for (let child of element.childNodes) {
          content += this.cleanHtmlElement(child);
        }
        
        // 自闭合标签
        const selfClosingTags = ['br', 'hr', 'img'];
        if (selfClosingTags.includes(tagName)) {
          return `<${tagName}${attributes} />`;
        }
        
        return `<${tagName}${attributes}>${content}</${tagName}>`;
      }
      
      return '';
    },
    
    // 转义HTML文本内容（只转义必要的字符）
    escapeHtmlText(text) {
      if (typeof text !== 'string') return '';
      return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
    },
    
    // 转义HTML属性值（保持URL的完整性）
    escapeHtmlAttribute(value) {
      if (typeof value !== 'string') return '';
      
      // 如果是URL，只转义必要的字符，保持URL结构
      if (value.startsWith('http://') || value.startsWith('https://') || value.startsWith('/')) {
        return value
          .replace(/"/g, '&quot;')
          .replace(/'/g, '&#39;');
      }
      
      // 普通属性值，转义所有特殊字符
      return value
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
    },

    cancel() {
      this.$router.go(-1)
    },
    
    reset() {
      this.form = {
        id: null,
        thumbnailUrl: null,
        title: null,
        desc: null,
        content: null,
        linkUrl: null,
        typeId: null,
        bannerPage: null,
        createTime: null,
        updateTime: null
      }
      this.croppedImageBlob = null
      this.resetForm("form")
    },
    
    async submitForm() {
      this.$refs["form"].validate(async valid => {
        if (valid) {
          // 处理content字段，确保是合规的HTML字符串
          if (this.form.content) {
            console.log('清理前的content:', this.form.content);
            
            // 可以选择是否进行HTML清理（如果遇到问题可以跳过）
            const shouldCleanHtml = true; // 设置为false可以跳过HTML清理
            
            if (shouldCleanHtml) {
              // 清理和转义HTML内容
              this.form.content = this.sanitizeHtmlContent(this.form.content)
              console.log('清理后的content:', this.form.content);
            } else {
              console.log('跳过HTML清理，使用原始内容');
            }
          }
          
          // 处理图片上传（新增或修改时）
          if (this.croppedImageBlob) {
            try {
              const formData = new FormData()
              formData.append('file', this.croppedImageBlob, 'news.png')
              formData.append('type', 3)
              const res = await uploadNewsFile(formData)
              if (res && res.code === 200 && res.fileName) {
                this.form.thumbnailUrl = res.fileName || res.url
              } else {
                this.$modal.msgError("图片上传失败")
                return
              }
            } catch (e) {
              this.$modal.msgError("图片上传失败")
              return
            }
          }
          
          // 显示最终提交的数据
          console.log('最终提交的表单数据:', JSON.stringify(this.form, null, 2));
          
          if (this.form.id != null) {
            updateNews(this.form).then(response => {
              this.$modal.msgSuccess("修改成功")
              this.$router.back()
            }).catch(error => {
              this.$modal.msgError("修改失败：" + (error.message || "未知错误"))
            })
          } else {
            addNews(this.form).then(response => {
              this.$modal.msgSuccess("新增成功")
              this.$router.back()
            }).catch(error => {
              this.$modal.msgError("新增失败：" + (error.message || "未知错误"))
            })
          }
        }
      })
    },
    
    // EditImage组件回调方法
    onImageCropped(blob, base64Url) {
      this.croppedImageBlob = blob
      console.log('图片裁剪完成:', blob, base64Url)
    },
    
    onImageRemoved() {
      this.croppedImageBlob = null
      console.log('图片已删除')
    },
    
    // Editor组件事件处理
    onEditorChange(eventName, ...args) {
      console.log('Editor change event:', eventName, args)
    },
    
    onEditorTextChange(delta, oldDelta, source) {
      console.log('Editor text change:', { delta, oldDelta, source })
    },
    
    onEditorSelectionChange(range, oldRange, source) {
      console.log('Editor selection change:', { range, oldRange, source })
    },
    
    // 自定义图片处理器 - 参考park_config的实现方式
    handleImageAdded(file, Editor, cursorLocation, resetUploader) {
      console.log('=== handleImageAdded 被调用 ===')
      console.log('文件信息:', file.name, file.size, file.type)
      console.log('Editor实例:', Editor)
      console.log('光标位置:', cursorLocation)
      console.log('重置函数:', resetUploader)
      console.log('开始处理图片上传:', file.name, file.size)
      
      // 检查token
      // const token = getToken()
      // console.log('当前token:', token ? token.substring(0, 20) + '...' : 'null')
      
      // 创建FormData对象
      const formData = new FormData()
      formData.append("file", file)
      formData.append("type", 3) // 新闻图片类型
      
      // 使用uploadNewsFile API上传图片
      uploadNewsFile(formData)
        .then(result => {
          console.log('图片上传结果:', result)
          if (result && result.code === 200) {
            // 获取图片URL
            const url = result.fileName || result.url || result.newFileName
            if (url) {
              // 构建完整的图片URL
              const fullUrl = this.getFullImageUrl(url)
              console.log('完整图片URL:', fullUrl)
              
              // 在光标位置插入图片
              Editor.insertEmbed(cursorLocation, "image", fullUrl)
              // 重置上传器
              resetUploader()
              this.$message.success("图片上传成功")
            } else {
              this.$message.error("图片上传失败：未获取到图片URL")
            }
          } else {
            this.$message.error("图片上传失败：" + (result.msg || "未知错误"))
          }
        })
        .catch(err => {
          console.error('图片上传失败:', err)
          this.$message.error("图片上传失败：" + (err.message || "网络错误"))
        })
    },
    
    // 获取完整图片URL
    getFullImageUrl(imageUrl) {
      if (!imageUrl) return '';
      if (/^(http|https):\/\//.test(imageUrl) || imageUrl.startsWith('data:image/')) {
        return imageUrl;
      }
      if (imageUrl.startsWith('/')) {
        return this.BASE_API + imageUrl;
      }
      return BASE_FILE_URL + imageUrl;
    }
  }
}
</script>

<style scoped lang="scss">
.form-actions {
  text-align: center;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #ebeef5;
}

.el-card {
  margin: 20px;
  
  .el-card__header {
    background-color: #f5f7fa;
    border-bottom: 1px solid #ebeef5;
  }
}
</style>
